<template>
	<div ref="bpmnContainer" style="width:100%;height:600px;"></div>
</template>
 
<script setup lang="ts" name="processStateViewer">
import BpmnModeler from 'bpmn-js/lib/Modeler';
import Canvas from 'diagram-js/lib/core/Canvas'
import EventBus from 'diagram-js/lib/core/EventBus'
import Overlays from 'diagram-js/lib/features/overlays/Overlays'
import { getDataDictionaryList } from '/@/utils/cacheDic';
import { ElMessage } from 'element-plus'
import { onMounted, reactive, ref } from 'vue'
import { TaskVo, workflowApi } from '/@/api/sys/workflow-api'
import { formatDate } from '/@/utils/formatTime'
const bpmnContainer = ref<HTMLElement | null>(null)
const props = defineProps({
	processId: {
		type: String,
		default: () => '0'
	},
	processDefId: {
		type: String,
		default: () => {
			return ''
		}
	}
})
let bpmnModeler: BpmnModeler;
const state = reactive({
  showToolTip: false,
  tooltipComponent: {
    template: '',
  },
  hisProcessRecordData: [] as TaskVo[],
  dataDictionaryList: {} as any,

})
// 页面加载时
// read://https_blog.csdn.net/?url=https%3A%2F%2Fblog.csdn.net%2Fm0_59792807%2Farticle%2Fdetails%2F133794214
onMounted(() => {
  // 数据字典
	getDataDictionaryList(state.dataDictionaryList, ["ProcessRecordState", "processResult"])
	if(props.processId && bpmnContainer.value){
		bpmnModeler = new BpmnModeler({
			container: bpmnContainer.value,
			additionalModules: [
				{
					paletteProvider:["value",''],//禁用/清空左侧工具栏
					labelEditingProvider:["value",''],//禁用节点编辑
					contextPadProvider:["value",''],//禁用图形菜单
					bendpoints:["value",{}],//禁用连线拖动
					zoomScroll:["value",''],//禁用滚动
					moveCanvas:['value',''],//禁用拖动整个流程图
					move:['value','']//禁用单个图形拖动
				}
			]
		})
		workflowApi.getResourceAndStateByProcessId(props.processId).then(data=> {
			bpmnModeler.importXML(data.data.resourceXml).then(() => {
				bpmnModeler.get<Canvas>('canvas').zoom('fit-viewport')
				// 画节点
				if (data.data.activeList && data.data.activeList.length > 0) {
          data.data.activeList.forEach((act: any) => {
            if(act.activityInstanceState === 0){
              bpmnModeler.get<Canvas>('canvas').addMarker(act.activityId, 'highlightActive')
						}else{
              bpmnModeler.get<Canvas>('canvas').addMarker(act.activityId, 'highlight')
						}
					})
				}
				// 画流线
				if (data.data.seqIds && data.data.seqIds.length > 0) {
          data.data.seqIds.forEach((s: string) => {
            bpmnModeler.get<Canvas>('canvas').addMarker(s, 'highlight-line')
					})
				}
        workflowApi.getHisTaskByProcessId(props.processId).then((data) => {
          state.hisProcessRecordData = data.data
          bindEvents()
        })
			})
		})
	}
})
const bindEvents = () => {
  const eventBus = bpmnModeler.get<EventBus>('eventBus')
  const overlays = bpmnModeler.get<Overlays>('overlays')
  eventBus.on('element.hover', (e) => {
    if(e.element.type === 'bpmn:UserTask'){
      genNodeDetailBox(props.processId, e.element.id, e, overlays)
    }
  })
  eventBus.on('element.out', (e) => {
    state.showToolTip = false
    if(e.element.type === "bpmn:UserTask" ){
      // popoverVisible.value = false;
    }
    overlays.clear()
  })
}
//数据字典回显
const dataDictionaryFilter = (msg: any, obj: any) => {
	if (obj) {
		return obj.get(msg)
	}
}
const genNodeDetailBox = (processId: string, taskKey: string, elment: any, overlays: Overlays) => {
  state.showToolTip = true
  const tempDiv = document.createElement('div')
  state.hisProcessRecordData.forEach(item => {
    if(taskKey == item.taskKey){
      const popoverEl = document.getElementById('flowMsgPopover')
      state.tooltipComponent = {
        template: `
                <p>
                  审批人员：<span class="approvePersonCss">${item.assigneeName}</span>
                </p>
                <p>处理状态：${dataDictionaryFilter(item.taskState, state.dataDictionaryList['ProcessRecordState'] || '')}</p>
                <p>处理结果：${dataDictionaryFilter(item.description, state.dataDictionaryList['processResult']) || ''}</p>
                <p>处理意见：${item.approveAdvice}</p>
                <p>开始时间：${item.startTime ? formatDate(new Date(item.startTime), 'YYYY-mm-dd HH:MM:SS') : ''}</p>
                <p>结束时间：${item.endTime ? formatDate(new Date(item.endTime), 'YYYY-mm-dd HH:MM:SS') : ''}</p>
                <p>审批耗时：${item.durationInSecond || ''}秒</p>
            `
      }
    }
  })
  tempDiv.innerHTML= state.tooltipComponent.template;
  tempDiv.className = 'tipBox';
  tempDiv.style.width = '270px';
  tempDiv.style.background = 'rgba(255, 255, 255, .6)'
  overlays.add(taskKey, 'note', {
    position: {top: elment.element.height, left: 0},
    html: tempDiv
  })
}
</script>
<style lang="scss">
  .bpmn-containers {
    background-color: #ffffff;
    width: 100%;
    height: 420px;
  }
  .bpmn-canvas {
    width: 100%;
    height: 100%;
  }
  .highlight:not(.djs-connection) .djs-visual > :nth-child(1) {
    fill: rgba(180, 241, 180, 1) !important; /* color elements as green */
  }
  .highlight g.djs-visual >:nth-child(1) {
    stroke: rgba(0, 190, 0, 1) !important;
  }
	.highlightActive:not(.djs-connection) .djs-visual > :nth-child(1) {
    fill: rgba(180, 241, 180, 1) !important; /* color elements as green */
  }
	.highlightActive g.djs-visual >:nth-child(1) {
    stroke: rgb(190, 70, 0) !important;
  }
  .highlight-line g.djs-visual >:nth-child(1) {
    stroke: rgba(0, 190, 0, 1) !important;
  }
  .highlight-line{
    path{
      marker-end: url('#greenMarker') !important;
    }
  }
  .highlight{
    .djs-visual{
      animation: dynamicNode 18S linear infinite;
      -webkit-animation: dynamicNode 18S linear infinite;
      -webkit-animation-fill-mode: forwards;
    }
  }
 
  @keyframes dynamicNode {
    to {
      stroke-dashoffset: 100%;
    }
  }
  @-webkit-keyframes dynamicNode {
    to {
      stroke-dashoffset: 100%;
    }
  }
  .bjs-powered-by{
    display: none;
  }
 
  .tipBox {
    font-size: var(--font-size-6);
    .ant-popover-arrow{
      display: none;
    }
  }
  .tipBox {
    width: 300px;
    background: #fff;
    border-radius: 4px;
    border: 1px solid #ebeef5;
    padding: var(--spacing-normal-2);
    .ant-popover-arrow{
      display: none;
    }
    .popover-title {
      font-size: 16px;
      line-height: 12px;
      margin: 0;
    }
    p{
      line-height: 28px;
      margin:0;
      padding:0;
    }
  }
  .approvePersonCss{
    color: var(--theme-custom-color);
    background-color: var(--theme-custom-color_1);
    border: 1px solid var(--theme-custom-color_2);
    padding: 4px;
  }
</style>
